using ICSharpCode.TextEditor.Document;

namespace ICSharpCode.TextEditor.Util
{
	public class LookupTable
	{
		private class Node
		{
			public string word;

			public object color;

			private Node[] children;

			public Node this[int index]
			{
				get
				{
					if (this.children != null)
					{
						return this.children[index];
					}
					return null;
				}
				set
				{
					if (this.children == null)
					{
						this.children = new Node[256];
					}
					this.children[index] = value;
				}
			}

			public Node(object color, string word)
			{
				this.word = word;
				this.color = color;
			}
		}

		private Node root = new Node(null, null);

		private bool casesensitive;

		private int length;

		public int Count => this.length;

		public object this[IDocument document, LineSegment line, int offset, int length]
		{
			get
			{
				if (length == 0)
				{
					return null;
				}
				Node node = this.root;
				int num = line.Offset + offset;
				if (this.casesensitive)
				{
					for (int i = 0; i < length; i++)
					{
						int index = (int)document.GetCharAt(num + i) % 256;
						node = node[index];
						if (node == null)
						{
							return null;
						}
						if (node.color != null && TextUtility.RegionMatches(document, num, length, node.word))
						{
							return node.color;
						}
					}
				}
				else
				{
					for (int j = 0; j < length; j++)
					{
						int index2 = (int)char.ToUpper(document.GetCharAt(num + j)) % 256;
						node = node[index2];
						if (node == null)
						{
							return null;
						}
						if (node.color != null && TextUtility.RegionMatches(document, this.casesensitive, num, length, node.word))
						{
							return node.color;
						}
					}
				}
				return null;
			}
		}

		public object this[string keyword]
		{
			set
			{
				Node node = this.root;
				Node node2 = this.root;
				if (!this.casesensitive)
				{
					keyword = keyword.ToUpper();
				}
				this.length++;
				for (int i = 0; i < keyword.Length; i++)
				{
					int index = (int)keyword[i] % 256;
					bool flag = keyword[i] == '\\';
					node2 = node2[index];
					if (node2 == null)
					{
						node[index] = new Node(value, keyword);
						break;
					}
					if (node2.word != null && node2.word.Length != i)
					{
						string word = node2.word;
						object color = node2.color;
						node2.color = (node2.word = null);
						this[word] = color;
					}
					if (i == keyword.Length - 1)
					{
						node2.word = keyword;
						node2.color = value;
						break;
					}
					node = node2;
				}
			}
		}

		public LookupTable(bool casesensitive)
		{
			this.casesensitive = casesensitive;
		}
	}
}
